//
//  NSString+Coder.swift
//  OMTCoreKit-Swift
//
//  Created by 昭荣伊 on 2018/12/7.
//

import Foundation
import CoreGraphics

extension String {
    
    /// URL 编码
    public var URLEncode: String {
        get {
            return self.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) ?? self
        }
    }
    
    /// URL 解码
    public var URLDecode: String {
        get {
            return self.removingPercentEncoding ?? self
        }
    }
    
    /// 去空格空行
    ///
    /// - Returns: 去除后的字符串
    public func trim() -> String {
        return self.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
    }
    
    
    /// 获取文本宽高
    ///
    /// - Parameters:
    ///   - font: 字体
    ///   - maxSize: 最大宽高
    /// - Returns: 宽高
    public func getSize(_ font: UIFont, _ maxSize: CGSize) -> CGSize {
        let textSize = (self as NSString).boundingRect(with: maxSize, options: [.usesLineFragmentOrigin, .usesLineFragmentOrigin], attributes: [.font : font], context: nil).size
        let textWidth = min(maxSize.width, textSize.width)
        let textHeight = min(maxSize.height, textSize.height)
        return CGSize(width: textWidth, height: textHeight)
    }
    
    
    /// 获取文本宽高
    ///
    /// - Parameters:
    ///   - font: 字体
    ///   - maxWidth: 最大宽度
    /// - Returns: 宽高
    public func getSize(_ font: UIFont, _ maxWidth: CGFloat) -> CGSize {
        return self.getSize(font, CGSize(width: maxWidth, height: CGFloat(MAXFLOAT)))
    }
    
    
    /// 获取文本宽度
    ///
    /// - Parameter font: 字体
    /// - Returns: 宽度
    public func getWidth(_ font: UIFont) -> CGFloat {
        return self.getSize(font, CGFloat(MAXFLOAT)).width
    }
    
    /// 获取文本高度
    ///
    /// - Parameter font: 字体
    /// - Returns: 高度
    public func getHeight(_ font: UIFont) -> CGFloat {
        return self.getSize(font, CGFloat(MAXFLOAT)).height
    }
    
    
    /// 给 URL 字符串添加参数
    ///
    /// - Parameter params: 参数
    /// - Returns: 处理后的字符串
    public mutating func appendURLParams(_ params: Dictionary<String, String>) -> String {
        if params.keys.count < 1 {
            return self
        }
        
        var pairs: [String] = [String]()
        for (key, value) in params {
            pairs.append("\(key)=\(value.URLEncode)")
        }
        
        let URL = NSURL.init(string: self)
        if URL == nil {
            return self
        }
        self.append(((URL?.query) != nil) ? "&" : "?")
        self.append(pairs.joined(separator: "&"))
        
        return self
    }
    
    
    /// 获取 URL 中的参数
    ///
    /// - Returns: 参数
    public func URLParams() -> Dictionary<String, String>? {
        let url = NSURL.init(string: self)
        if url != nil {
            let queryItems = NSURLComponents.init(url: url! as URL, resolvingAgainstBaseURL: false)?.queryItems ?? []
            if (queryItems.count > 0) {
                var parameters:Dictionary<String, String> = Dictionary<String, String>()
                for item in queryItems {
                    parameters[item.name] = item.value?.URLDecode
                }
                return parameters
            }
        }
        return nil
    }
    
    /// 通过 key 获取 URL 参数
    ///
    /// - Parameter key: 参数名称
    /// - Returns: 值
    public func URLParamValueForKey(_ key: String) -> String? {
        return self.URLParams()?[key]
    }
    
    
    /// 是空字符串
    public var isEmpty: Bool {
        get {
            return self.trim().count < 1
        }
    }
    
    /// 不是空字符串
    public var isNotEmpty: Bool {
        get {
            return !self.isEmpty
        }
    }
    
    /// 是阿拉伯字符
    public var isArabic: Bool {
        get {
            if (self.isEmpty) {
                return false
            }
            
            var isArabic = false;
            self.enumerateSubstrings(in: startIndex..<endIndex, options: NSString.EnumerationOptions.byComposedCharacterSequences) { (substring, substringRange, enclosingRange, stop) -> () in
                if (self._isEmojiString(substring) || self._isSymbolString(substring)) {
                    return;
                }
                
                if (self._isArabicString(substring)) {
                    isArabic = true
                    stop = true
                    return
                } else {
                    isArabic = false
                    stop = true
                    return
                }
            }
            return isArabic
        }
    }
    
    /// 是否为符号字符串
    ///
    /// - Parameter string: 字符串
    /// - Returns: true 是 false 否
    private func _isSymbolString(_ string: String?) -> Bool {
        var isSymbol = false;
        if let string = string, string.count > 0 {
            let unicodeScalars: String.UnicodeScalarView = string.unicodeScalars
            if let scalar = unicodeScalars.first {
                let unicode = scalar.value
                if ((unicode >= 0x0020 && unicode <= 0x002F) ||
                    (unicode >= 0x003A && unicode <= 0x0040) ||
                    (unicode >= 0x2500 && unicode <= 0x2BFF) ||
                    (unicode >= 0x2000 && unicode <= 0x206F)) {
                    isSymbol = true;
                }
            }
        }
        return isSymbol
    }
    
    /// 是否为 Emoji 字符串
    ///
    /// - Parameter string: 字符串
    /// - Returns: true 是 false 否
    private func _isEmojiString(_ string: String?) -> Bool {
        var isEmoji = false;
        if let string = string, string.count > 0 {
            let unicodeScalars: String.UnicodeScalarView = string.unicodeScalars
            let count = unicodeScalars.count
            if let scalar = unicodeScalars.first {
                let unicode = scalar.value
                if ((unicode >= 0xD800 && unicode <= 0xDB7F) ||
                    (unicode >= 0x1F600 && unicode <= 0x1F64F) ||
                    (unicode >= 0x2460 && unicode <= 0x26FF) ||
                    (unicode >= 0x2000 && unicode <= 0x200F) ||
                    (unicode >= 0x203C && unicode <= 0x209F) ||
                    (unicode >= 0x2100 && unicode <= 0x214F) ||
                    (unicode >= 0x0030 && unicode <= 0x007A && count > 1)) {
                    isEmoji = true;
                }
            }
        }
        return isEmoji
    }
    
    /// 是否为阿拉伯字符串
    ///
    /// - Parameter string: 字符串
    /// - Returns: true 是 false 否
    private func _isArabicString(_ string: String?) -> Bool {
        var isArabic = false;
        if let string = string, string.count > 0 {
            let unicodeScalars: String.UnicodeScalarView = string.unicodeScalars
            if let scalar = unicodeScalars.first {
                let unicode = scalar.value
                if ((unicode >= 0x0600 && unicode <= 0x06FF) ||
                    (unicode >= 0x0750 && unicode <= 0x077f) ||
                    (unicode >= 0x08A0 && unicode <= 0x08FF) ||
                    (unicode >= 0xFB50 && unicode <= 0xFDFF) ||
                    (unicode >= 0xFE70 && unicode <= 0xFEFF)) {
                    isArabic = true;
                }
            }
        }
        return isArabic
    }
}
